#include <iostream>
#include <typeinfo>
#include <cassert>
#include <any>
class Any
{
public:
    Any()
        :_content(nullptr)
    {}
    template <class T>//T是协议的类型
    Any(const T& val)//外部传入一个类型，根据这个类型进行构造
        :_content(new placeholder<T>(val))
    {}
    Any(const Any& other)
        :_content(other._content == nullptr ? nullptr : other._content->Clone())
    {}
    ~Any()//销毁_content
    {
        delete _content;
    }
    Any& Swap(Any& other)
    {
        std::swap(_content, other._content);//交换类的指针
        return *this;
    } 
    template <class T> 
    Any& operator=(const T& val)//通过数据类型进行赋值
    {
        Any(val).Swap(*this);//Any(val)表示生成的临时对象，和this交换内部_content指针后将会被销毁
        return *this;
    }
    Any& operator=(const Any& other)//通过其他的Any对象进行赋值
    {
        Any(other).Swap(*this);//原先this中保存的值也被释放了
        return *this;
    }
public:
    template <class T>
    T* Get()//返回子类对象保存的数据的指针
    {
        assert(typeid(T) == _content->Type());//获取的类型和保存的数据类型不一致
        return &((placeholder<T>*)_content)->_val;
    }
private:
    class holder//父类
    {
    public:
        virtual ~holder(){}
    public:
        virtual const std::type_info& Type() = 0;//纯虚函数，获取子类对象保存的类型
        virtual holder* Clone() = 0;//纯虚函数，通过一个子类对象克隆出一个新的子类对象
    };

    template<class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T& val)
            :_val(val)
        {}
    public:
        virtual const std::type_info& Type()//获取子类对象保存的类型
        {
            return typeid(T);
        }
        virtual holder* Clone()//针对当前自身的对象，克隆出一个新的子类对象
        {
            return new placeholder(_val);
        }
    public:
        T _val;//T类型的数据
    };
    
    holder* _content;//指向父类的指针 
};
struct Test
{
    Test()
    {
        std::cout<< "构造函数" << std::endl;
    }
    Test(const Test& t)
    {
        std::cout<< "拷贝构造函数" << std::endl;
    }
    ~Test()
    {
        std::cout<< "析构函数" << std::endl;
    }
};
//模拟实现的any
// int main()
// {
//     Any a;
//     {
//         Test t;
//         a = t;  
//     }
//     a = 10;
//     int* pa = a.Get<int>();
//     std::cout << *pa << std::endl;

//     a = std::string("hello");
//     std::string* ps = a.Get<std::string>();
//     std::cout << *ps << std::endl;
//     return 0;
// }

//C++17中的any
int main()
{
    std::any a;
    a = 10;
    int* pi =std::any_cast<int>(&a);
    std::cout << *pi << std::endl; 
    a = std::string("hello");
    std::string* ps =std::any_cast<std::string>(&a);
    std::cout << *ps << std::endl; 
    return 0;
}